﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace LocalizationTest.Tools
{
  public partial class NameSpaceTreeView2 : UserControl
  {
    private char _separator;
    public class NodeProperties
    {
      public NodeProperties(bool isChecked, bool isKnown)
      {
        this.isChecked = isChecked;
        this.isKnown = isKnown;
      }
      public bool isChecked;
      public bool isKnown = true;
    }
    private Dictionary<string, NodeProperties> nodeIDs = new Dictionary<string, NodeProperties>();
    private List<TreeNode> treeNodesForExpansion;

    [Category("NameSpaceTreeView")]
    public Dictionary<string, NodeProperties> NodeIDs
    {
      get { return nodeIDs; }
      set { nodeIDs = value; }
    }
    [Category("NameSpaceTreeView")]
    public char Separator
    {
      get { return _separator; }
      set { _separator = value; }
    }
    [Category("NameSpaceTreeView")]
    public System.Windows.Forms.TreeView TreeView
    {
      get { return treeView; }
    }

    public NameSpaceTreeView2()
    {
      InitializeComponent();
      treeView.Sorted = true;
    }
    public void Clear()
    {
      nodeIDs.Clear();
      treeView.Nodes.Clear();
    }

    public void UpdateTree()
    {
      treeView.BeginUpdate();
      treeView.Nodes.Clear();
      object[] args = { treeView.Nodes, nodeIDs };
      treeNodesForExpansion = new List<TreeNode>();
      UpdateTreeView(treeView.Nodes, nodeIDs);
      foreach (TreeNode treeNode in treeNodesForExpansion)
      {
        TreeNode currentNode = treeNode;
        while (currentNode != null)
        {
          currentNode.Expand();
          currentNode = currentNode.Parent;
        }
      }
      treeView.EndUpdate();
    }
    public void UpdateTreeView(TreeNodeCollection root, Dictionary<string, NodeProperties> hashtableToAdd)
    {
      foreach (string key in nodeIDs.Keys)
      {
        TreeNodeCollection currentNodes = root;
        bool check = nodeIDs[key].isChecked;
        bool known = nodeIDs[key].isKnown;

        string[] parts = key.Split(_separator);
        for (int depth = 0; depth < parts.Length; depth++)
        {
          bool lastToken = depth == parts.Length - 1;
          int index = GetIndexOfNodeWithName(currentNodes, parts, depth);
          if (index != -1)
          {
            if (!lastToken) currentNodes = currentNodes[index].Nodes;
          }
          else
          {
            if (lastToken)
            {
              TreeNode newNode = new TreeNode(parts[depth]);
              newNode.Checked = check;
              if (!known) newNode.NodeFont = new Font("Arial", 8, FontStyle.Italic);
              currentNodes.Add(newNode);
              if (check)
              {
                treeNodesForExpansion.Add(newNode);
              }
            }
            else
            {
              TreeNode newNode = new TreeNode(parts[depth]);
              currentNodes.Add(newNode);
              currentNodes = newNode.Nodes;
            }
          }
        }
      }
    }

    private static int GetIndexOfNodeWithName(TreeNodeCollection currentNodes, string[] parts, int depth)
    {
      int index = -1;
      int counter = 0;
      foreach (TreeNode treeNode in currentNodes)
      {
        if (treeNode.Text == parts[depth])
        {
          index = counter;
        }
        counter++;
      }
      return index;
    }

    public void AddOrConfirmValue(string valueID)
    {
      if (valueID == "") return;
      bool somethingAddedOrConfirmed = false;
      if (!nodeIDs.ContainsKey(valueID))
      {
        nodeIDs[valueID] = new NodeProperties(false, true);
        somethingAddedOrConfirmed = true;
      }
      else
      {
        somethingAddedOrConfirmed = !nodeIDs[valueID].isKnown;
      }
      nodeIDs[valueID].isKnown = true;
      if (somethingAddedOrConfirmed) UpdateTree();
    }

    public void AddValueID(string valueID, bool check)
    {
      if (valueID == "") return;
      if (!nodeIDs.ContainsKey(valueID))
      {
        nodeIDs[valueID] = new NodeProperties(check, true);
      }
      nodeIDs[valueID].isChecked = check;
      nodeIDs[valueID].isKnown = true;
    }
    public void SetCheck(string valueID, bool check)
    {
      if (valueID == "") return;
      if (nodeIDs.ContainsKey(valueID))
      {
        nodeIDs[valueID].isChecked = check;
      }
      else
      {
        nodeIDs[valueID] = new NodeProperties(true, false);
        nodeIDs[valueID].isChecked = true;
        nodeIDs[valueID].isKnown = false;
      }
    }

    private TreeNode GetTreeNode(string valueID)
    {
      string[] parts = valueID.Split(_separator);
      TreeNodeCollection nodeCollection = treeView.Nodes;
      TreeNode toReturn = null;
      foreach (string part in parts)
      {
        foreach (TreeNode node in nodeCollection)
        {
          toReturn = null;
          if (node.Text == part)
          {
            nodeCollection = node.Nodes;
            toReturn = node;
            break;
          }
        }
        if (toReturn == null) return null;
      }
      return toReturn;
    }

    public string GetCheckedState()
    {
      /*
      string result = "";
      foreach (TreeNode node in treeView.Nodes)
      {
        if (node.Nodes.Count == 0)
        {
          if (node.Checked)
          {
            result += node.FullPath + ";";
          }
        }
        else
        {
          result += CreateCheckedStateString(node);
        }
      }
      return result;
       */
      return "123456";
    }

    private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
    {
      string fullPath = e.Node.FullPath;
      fullPath = fullPath.Replace("\\", ":");
      if (nodeIDs.ContainsKey(fullPath)) nodeIDs[fullPath].isChecked = e.Node.Checked;

      // update all nodes behind the updated node
      foreach (TreeNode node in e.Node.Nodes)
      {
        if (node.Nodes != null)
        {
          node.Checked = e.Node.Checked;
        }
      }
      // update parent node
      bool slct = false;
      bool unslct = false;

      try
      {
        if (e.Node.Parent != null)
          foreach (TreeNode node in e.Node.Parent.Nodes)
          {
            if (node.Checked)
            {
              slct = true;
            }
            else
              if (!node.Checked)
              {
                unslct = true;
              }
          }
        //foreach ends
        if (slct && !unslct && !e.Node.Parent.Checked)
        {
          e.Node.Parent.Checked = true;
        }
        else
          if (!slct && unslct && e.Node.Parent.Checked)
          {
            e.Node.Parent.Checked = false;
          }
      }
      catch (Exception exception)
      {
        System.Windows.Forms.MessageBox.Show(exception.Message, "NameSpaceTreeView::treeView_AfterCheck");
      }
    }
  }
}
